package com.fessc.develop.handler.processor.request;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fessc.develop.base.Result;
import com.fessc.develop.entity.comvo.CommonHeadSendVo;
import com.fessc.develop.entity.comvo.CommonSendVo;
import com.fessc.develop.entity.dbvo.SettleTrade;
import com.fessc.develop.entity.dbvo.TFaceCheck;
import com.fessc.develop.entity.dbvo.TOrgUrlManage;
import com.fessc.develop.handler.SignHandler;
import com.fessc.develop.model.enums.*;
import com.fessc.develop.service.interfaces.ISettleTradeListService;
import com.fessc.develop.service.interfaces.ISettleTradeService;
import com.fessc.develop.service.interfaces.ITFaceCheckService;
import com.fessc.develop.service.interfaces.ITOrgUrlManageService;
import com.fessc.develop.utils.BusiUtil;
import com.fessc.develop.utils.DateUtil;
import com.fessc.develop.utils.OkHttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

@Slf4j
@Service
public class ComFaceCheckSyncService implements IBaseService {

    @Resource
    private SignHandler signHandler;

    @Resource
    private ITOrgUrlManageService tOrgUrlManageService;

    @Resource
    private ISettleTradeService settleTradeService;

    @Resource
    private ISettleTradeListService settleTradeListService;

    @Resource
    private ITFaceCheckService faceCheckService;

    @Resource
    private OkHttpUtil okHttpUtil;

    @Override
    public String getServiceCode() {
        return EnumServiceCode.PLAT_MP0006.toString();
    }

    @Override
    public Result process(JSONObject request) {
        log.info("市场交易平台人脸识别结果同步请求报文: " + request);
        CommonSendVo<Object> commonSendVo = new CommonSendVo<>();
        JSONObject bodyObject = request.getJSONObject(EnumJsonProperty.REQ_BODY.toString());
        JSONObject headObject = request.getJSONObject(EnumJsonProperty.REQ_SYS_HEAD.toString());
        CommonHeadSendVo commonHeadSendVo = JSON.parseObject(headObject.toJSONString(), CommonHeadSendVo.class);
        commonHeadSendVo.setServiceCode(EnumServiceCode.COM_FS0009.toString());
        commonSendVo.setCommonHeadSendVo(commonHeadSendVo);
        commonSendVo.setBody(bodyObject);
        log.info("互联互通转发人脸识别结果同步请求明文: " + JSON.toJSONString(commonSendVo));

        //根据机构查询配置表获取URL,通用默认一个机构只有一个URL
        TOrgUrlManage orgUrlManage = tOrgUrlManageService.getOrgUrlByOrgCodeAndKey(commonHeadSendVo.getBankId(), EnumOrgType.BANK.toString(), EnumServiceCode.COM_FS0009.toString());
        // 发送报文body加密
        String bodyDecrypt = signHandler.encrypt(JSON.toJSONString(commonSendVo.getBody()), orgUrlManage.getPubCert());
        commonSendVo.setBody(bodyDecrypt);
        Map<String, String> requestHeaders = okHttpUtil.getRequestHeaders(orgUrlManage.getAppKey(), orgUrlManage.getInterfaceUrl(), commonHeadSendVo.getBankId());
        log.info("互联互通转发人脸识别结果同步请求密文：" + JSON.toJSONString(commonSendVo));

        //接口推送
        String responseEncryptJson = "";  //返回加密报文
        JSONObject responseDecryptJson = new JSONObject();  //解密后报文
        try {
            // 先解析返回报文
            responseEncryptJson = okHttpUtil.doPostJson(orgUrlManage.getInterfaceUrl(), JSON.toJSONString(commonSendVo), requestHeaders);
            responseDecryptJson = JSON.parseObject(responseEncryptJson);
            log.info("人脸识别结果同步响应报文(解密前): " + JSON.toJSONString(responseDecryptJson));
            String date = responseDecryptJson.getString(EnumJsonProperty.RES_DATA.toString());
            // 解密DATA部分
            if (BusiUtil.isNotNull(date)) {
                responseDecryptJson.put(EnumJsonProperty.RES_DATA.toString(), JSONObject.parseObject(signHandler.decrypt(date)));
            }
            log.info("人脸识别结果同步响应报文(解密后): " + JSON.toJSONString(responseDecryptJson));
            //更新跨境付汇交易结果，这个情况应该很少，实际上，数据推送到银行前已经完成短信验证码与人脸核验
            if (BusiUtil.isEquals(bodyObject.getString("orderType"), "3")) {
                updateSettleTradeStatus(responseDecryptJson, bodyObject.getString("orderNo"));
            }
        } catch (Exception e) {
            log.info("人脸识别结果同步响应报文解析失败: " + e.getMessage());
        }

        try {
            log.info("保存人脸识别结果同步信息：" + bodyObject.getString("orderNo") + "，" + bodyObject.getString("faceId") + "，" + bodyObject.getString("mobilePhone") + "，" + bodyObject.getString("smsCod"));
            TFaceCheck faceCheck = new TFaceCheck();
            faceCheck.setCheckType("3");
            faceCheck.setLogId(MDC.get("lodId"));
            faceCheck.setBankId(commonHeadSendVo.getBankId());
            faceCheck.setOrgCode(commonHeadSendVo.getOrgCode());
            faceCheck.setRequestTime(DateUtil.getCurrentLocalDateTime());
            faceCheck.setOrderNo(bodyObject.getString("orderNo"));
            faceCheck.setFaceId(bodyObject.getString("faceId"));
            faceCheck.setIdName(bodyObject.getString("mobilePhone"));
            faceCheck.setSmsCode(bodyObject.getString("smsCod"));
            faceCheck.setResponseCode(BusiUtil.subFoolString(responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString(EnumJsonProperty.RES_FACESTATUS.toString()), 20));
            faceCheck.setResponseLog(BusiUtil.subFoolString(responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString()).getString(EnumJsonProperty.RES_FACEMSG.toString()), 100));
            faceCheckService.save(faceCheck);
        } catch (Exception e) {
            log.info("保存人脸识别结果同步异常: " + e.getMessage());
        }

        // 返回报文，如果为空，按失败处理
        Result result = new Result(responseDecryptJson.getString(EnumJsonProperty.RES_STATUS_CODE.toString()), responseDecryptJson.getString(EnumJsonProperty.RES_STATUS_MSG.toString()));
        JSONObject jsonData = responseDecryptJson.getJSONObject(EnumJsonProperty.RES_DATA.toString());
        jsonData = BusiUtil.isNull(jsonData) ? (new JSONObject()) : jsonData;
        jsonData.put(EnumJsonProperty.RES_FACESTATUS.toString(), BusiUtil.nvl(jsonData.getString(EnumJsonProperty.RES_FACESTATUS.toString()), EnumResultType.FAIL.getStatusCode()));
        jsonData.put(EnumJsonProperty.RES_FACEMSG.toString(), BusiUtil.nvl(jsonData.getString(EnumJsonProperty.RES_FACEMSG.toString()), EnumResultType.FAIL.getMsg()));
        result.setData(jsonData);
        log.info("市场交易平台人脸识别结果同步返回报文: " + JSON.toJSONString(result));
        return result;
    }

    private void updateSettleTradeStatus(JSONObject responseJson, String orderNo) {
        try {
            // 判断人脸识别结果同步是否通过（0-未通过 1-通过），如果通过，根据返回结果如下处理
            // 1、如果未发送银行，不做更新处理，待发起跨境付汇接口时，再进行更新
            // 2、如果已发送银行，返回交易失败，修改交易状态为失败
            // 3、如果已发送银行，返回交易成功，不做更新处理，系统定时通过跨境付汇交易状态查询接口，再进行更新
            String statusCode = responseJson.getString(EnumJsonProperty.RES_STATUS_CODE.toString());
            if (BusiUtil.isEquals(statusCode, EnumResultType.COM_SUCCESS.getStatusCode())) {
                JSONObject responseData = responseJson.getJSONObject(EnumJsonProperty.RES_DATA.toString());
                String faceStatus = responseData.getString(EnumJsonProperty.RES_FACESTATUS.toString());  //人脸识别状态：0-未通过 1-通过
                String faceMsg = responseData.getString(EnumJsonProperty.RES_FACEMSG.toString());
                String tranState = BusiUtil.nvl(responseData.getString(EnumJsonProperty.RES_TRANSTATE.toString()), EnumResultType.COM_SUCCESS.getStatusCode());  //业务状态：000000-正常，其他非正常，空值默认成功
                String tranMsg = responseData.getString(EnumJsonProperty.RES_TRANMSG.toString());
                SettleTrade settleTrade = settleTradeService.getSettleTradeBySettleId(orderNo);
                if (BusiUtil.isEquals(faceStatus, "1") && BusiUtil.isNotNull(tranState) && BusiUtil.isNotNull(settleTrade) &&
                        BusiUtil.isNotEquals(EnumResultType.COM_SUCCESS.getStatusCode(), tranState) &&
                        BusiUtil.isEquals(settleTrade.getReviewStatus(), "0") &&
                        BusiUtil.isEquals(settleTrade.getOrderStatus(), "Y") &&
                        BusiUtil.isEquals(settleTrade.getPaymentType(), "B") &&
                        BusiUtil.isEquals(settleTrade.getPaymentTypeSend(), "Y")) {
                    log.info("该笔跨境付汇人脸核验结果成功：" + orderNo);
                    settleTrade.setReviewStatus(EnumPaymentStatus.SETTLE_REVIEW_FAIL.toString());
                    settleTrade.setRejectDate(DateUtil.getCurrentLocalDateTime());
                    settleTrade.setRejectPerformer(settleTrade.getOrgCode());
                    settleTrade.setRemark("银行驳回交易失败原因：" + BusiUtil.nvl(tranMsg, EnumPaymentStatus.PAYMENT_FAIL_LOG.toString()));
                    settleTrade.setCancelSend(EnumPaymentStatus.SETTLE_CANCEL_SEND.toString());
                    log.info("人脸结果同步返回交易失败，修改状态为失败：" + orderNo);
                    settleTradeService.updateSettleTradeStatusRefidsLog(settleTrade, EnumPaymentStatus.PAYMENT_FAIL.toString()); //更新交易失败状态
                    log.info("更新跨境付汇明细状态为失败：" + orderNo);
                    settleTradeListService.updateSettleTradeListStatus(settleTrade.getSettleId(), "N");
                } else {
                    log.info("该笔跨境付汇未发送银行或者人脸核验结果失败：" + orderNo);
                }
            }
        } catch (Exception e) {
            log.info("人脸核验结果同步更新交易状态发生异常：" + e.getMessage());
        }

    }

}
